﻿using System;
using System.Reflection;
using System.Reflection.Emit;

namespace LivePatterns
{
	/// <summary>
	/// 
	/// </summary>
	internal static class ILGeneratorExtensions
	{
		public static void LoadThis(this ILGenerator il)
		{
			il.Emit(OpCodes.Ldarg_0);
		}

		public static void ThrowException(this ILGenerator il, Type exceptionType, string message)
		{
			il.Emit(OpCodes.Ldstr, message);
			il.Emit(OpCodes.Newobj, exceptionType.GetConstructor(new Type[] { typeof(string) }));
			il.Emit(OpCodes.Throw);
		}

		public static void LoadAllArguments(this ILGenerator il, MethodInfo method)
		{
			ParameterInfo[] parameters = method.GetParameters();

			if (parameters.Length >= 1)
				il.Emit(OpCodes.Ldarg_1);
			if (parameters.Length >= 2)
				il.Emit(OpCodes.Ldarg_2);
			if (parameters.Length >= 3)
				il.Emit(OpCodes.Ldarg_3);
			if (parameters.Length >= 4)
				for (int i = 4; i <= parameters.Length; i++)
				{
					il.Emit(OpCodes.Ldarg, (byte)i);
				}
		}

		public static void Return(this ILGenerator il)
		{
			il.Emit(OpCodes.Ret);
		}

		public static void ConstructObject(this ILGenerator il)
		{
			il.Emit(OpCodes.Ldarg_0);
			il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
		}
	}
}
